package org.ydsw.data.manage.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.ydsw.data.manage.entity.PageVo;
import org.ydsw.data.manage.entity.ScheduleJobEntity;
import org.ydsw.data.manage.mapper.ScheduleJobEntityMapper;
import org.ydsw.data.manage.schedule.ScheduleUtils;
import org.ydsw.data.manage.service.ScheduleJobService;
import org.ydsw.data.manage.utils.Constant;
import org.ydsw.data.manage.utils.DateUtil;
import tk.mybatis.mapper.entity.Example;

import java.util.List;

/**
 * 定时任务访问数据库的实现类
 * @author admin
 * @date 2021年01月07日
 */
@Slf4j
@Service
public class ScheduleJobServiceImpl implements ScheduleJobService {

	@Autowired
	private Scheduler scheduler;

	@Autowired
	private ScheduleJobEntityMapper scheduleJobEntityMapper;

	@Override
	public PageVo<ScheduleJobEntity> queryPage(Integer pageNum, Integer pageSize, ScheduleJobEntity scheduleJobEntity)  {
		PageHelper.startPage(pageNum, pageSize);

		Example o = new Example(ScheduleJobEntity.class);
		Example.Criteria criteria = o.createCriteria();
		criteria.andEqualTo("scheduleType", "数据管理");
		criteria.andNotEqualTo("methodName", "dealMaxStorage");
		List<ScheduleJobEntity> scheduleJobEntityList = scheduleJobEntityMapper.selectByExample(o);

		log.info("scheduleJobEntityList : {}", JSONArray.toJSONString(scheduleJobEntityList));

		PageInfo<ScheduleJobEntity> info = new PageInfo<>(scheduleJobEntityList);
		return new PageVo<>(info.getTotal(), scheduleJobEntityList);
	}

	/**
	 * 根据ID获取schedule_job表实列
	 * @param jobId
	 * @return ScheduleJobEntity
	 * @auther: admin
	 */
	@Override
	public ScheduleJobEntity queryEntity(Long jobId) {
		return scheduleJobEntityMapper.selectByPrimaryKey(jobId);
	}

	/**
	 * 查询有效状态的任务集合
	 * @return
	 */
	@Override
	public List<ScheduleJobEntity> queryList() {
		Example example = new Example(ScheduleJobEntity.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("status", 1);
		List<ScheduleJobEntity> scheduleJobEntityList = scheduleJobEntityMapper.selectByExample(example);
		log.info("queryList scheduleJobEntityList : {}", JSONArray.toJSONString(scheduleJobEntityList));
	    return scheduleJobEntityList;
	}

	/**
	 * 保存新数据
	 * 添加到执行器
	 * @param scheduleJob
	 * @author: admin
	 */
	@Override
	public void save(ScheduleJobEntity scheduleJob) {
		scheduleJob.setCreateTime(DateUtil.getCurrentTime());
		scheduleJob.setStatus(Constant.ScheduleStatus.NORMAL.getValue());
		log.info("save before scheduleJob : {}", JSONArray.toJSONString(scheduleJob));

		scheduleJobEntityMapper.insertScheduleJobEntity(scheduleJob);
		log.info("save after scheduleJob : {}", JSONArray.toJSONString(scheduleJob));

		//将新增加的任务添加到计划执行器里面
		ScheduleUtils.createScheduleJob(scheduler, scheduleJob);
	}

	/**
	 * 更新数据清除策略
	 * @param scheduleJob
	 * @return
	 * @author: admin
	 */
	@Override
	public void updateScheduleJobEntity(ScheduleJobEntity scheduleJob) {
		scheduleJobEntityMapper.updateByPrimaryKey(scheduleJob);
		log.info("updateScheduleJobEntity scheduleJob : {}", JSONArray.toJSONString(scheduleJob));
	}

	/**
	 * 更新数据
	 * 更新执行器
	 * @param scheduleJob status
	 * @return
	 * @author: admin
	 */
	@Override
	public void update(ScheduleJobEntity scheduleJob) {
		scheduleJobEntityMapper.updateByPrimaryKey(scheduleJob);
		log.info("update scheduleJob : {}", JSONArray.toJSONString(scheduleJob));

		//更新定时任务：
		ScheduleUtils.updateScheduleJob(scheduler, scheduleJob);
	}

	/**
	 * 批量删除数据，删除时还需要删除线程中运行的定时任务。
	 * @param jobIds
	 * @return
	 * @author: admin
	 */
	@Override
	public void deleteBatch(Long[] jobIds) {
		for(Long jobId : jobIds){
			//先将运行的JOB删除掉
			ScheduleUtils.deleteScheduleJob(scheduler, jobId);

			//在删除数据库中的数据
			scheduleJobEntityMapper.deleteByPrimaryKey(jobId);
		}
	}

	/**
	 * 运行任务，将任务从休眠状态调整为运行状态
	 * @param jobIds
	 * @author: admin
	 */
	@Override
	public void run(Long[] jobIds) {
		//解析传入的字符串
		for(Long jobId : jobIds){
			ScheduleUtils.run(scheduler, queryEntity(jobId));
		}
	}

	/**
	 * 更新任务状态，同时将线程中正在运行的任务暂停。
	 * @param jobIds
	 * @author: admin
	 */
	@Override
	public void pause(Long[] jobIds) {
		for(Long jobId : jobIds){
			//暂时线程里面的任务
			ScheduleUtils.pauseJob(scheduler, jobId);
			log.info("pause job ok, jobId : {}", jobId);

			//更新数据库里面的状态数据
			ScheduleJobEntity scheduleJobEntity = scheduleJobEntityMapper.selectByPrimaryKey(jobId);
			scheduleJobEntity.setStatus(Constant.ScheduleStatus.PAUSE.getValue());
			update(scheduleJobEntity);
		}
	}

	/**
	 * 更新任务状态，同时恢复线程中的暂停任务
	 * @param jobIds
	 */
	@Override
	public void resume(Long[] jobIds) {
		for(Long jobId : jobIds){
			//恢复进行任务
			ScheduleUtils.resumeJob(scheduler, jobId);
			log.info("resume job ok, jobId : {}", jobId);

			//更新数据库里面的状态数据
			ScheduleJobEntity scheduleJobEntity = scheduleJobEntityMapper.selectByPrimaryKey(jobId);
			scheduleJobEntity.setStatus(Constant.ScheduleStatus.NORMAL.getValue());
			update(scheduleJobEntity);
		}
	}

}
